package com.gitee.loyo;

import com.gitee.loyo.impl.BufferReadStream;
import io.vertx.core.*;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.http.*;
import io.vertx.core.http.impl.headers.HeadersMultiMap;

public class RequestReady {
    final HttpClient client;
    HttpMethod httpMethod;
    String uri;
    MultiMap headers = new HeadersMultiMap();
    BufferReadStream bodyReader;
    Future<HttpClientResponse> responseFuture;

    HttpClientRequest httpClientRequest;

    public RequestReady(HttpClient client) {
        this.client = client;
    }


    public void setHttpMethod(HttpMethod httpMethod) {
        this.httpMethod = httpMethod;
    }

    public void setUri(String uri) {
        this.uri = uri;
    }

    public void addHeader(String key, String value) {
        headers.add(key, value);
    }

    public void sendChunk(Context context, Buffer buffer) {
        if(bodyReader == null){
            synchronized (this){
                if(bodyReader == null){
                    bodyReader = new BufferReadStream(context);
                }
            }
        }
        ready();
        bodyReader.read(buffer);
    }

    public void end(Handler<AsyncResult<HttpClientResponse>> handler) {
        ready();
        responseFuture.onComplete(ar -> {
            if(httpClientRequest == null){
                // on error
                handler.handle(Future.failedFuture("unreached host"));
                return;
            }

            if(bodyReader != null && !bodyReader.tryEnd()){
                httpClientRequest.end().onComplete(event -> {
                    if(event.succeeded()){
                        System.out.println("成功");
                    }else{
                        event.cause().printStackTrace();
                    }
                });
            }
            handler.handle(ar);
        });
    }

    private void ready(){
        if(responseFuture == null){
            synchronized (this){
                if(responseFuture == null) {
                    RequestOptions requestOptions = new RequestOptions().setMethod(httpMethod).setURI(uri).setHeaders(headers);
                    responseFuture = client.request(requestOptions).compose(httpClientRequest -> {
                        if(httpClientRequest != null){
                            this.httpClientRequest = httpClientRequest;
                        }
                        if (bodyReader != null)
                            return httpClientRequest.send(bodyReader);
                        else
                            return httpClientRequest.send();
                    });
                }
            }
        }
    }

    public void close() {
        if(httpClientRequest != null){
            httpClientRequest.connection().close();
        }
    }
}
